import React, { useRef } from "react";
import { message } from "antd";
import { useComponentsStore, type Component } from "../../stores/components";
import { useComponentConfigStore } from "../../stores/component-config";
import { GoToLinkConfig } from "../Setting/actions/GoToLink";
import { ShowMessageConfig } from "../Setting/actions/ShowMessage";
import { CustomJsConfig } from "../Setting/actions/CustomJs";
import { ComponentMethodConfig } from "../Setting/actions/ComponentMethod";

export function Preview() {
    const { components } = useComponentsStore();
    const { componentConfig } = useComponentConfigStore();

    const handleEvent = (component: Component) => {
        const props: Record<string, any> = {};

        componentConfig[component.name].events?.forEach(event => {
            const eventConfig = component.props[event.name];
            if (eventConfig) {
                //const { type, url } = eventConfig;
                props[event.name] = (...args: any[]) => { // 接收方法的默认参数
                    eventConfig?.actions?.forEach((action: GoToLinkConfig | ShowMessageConfig | CustomJsConfig | ComponentMethodConfig) => {
                        if (action.type === 'goToLink') {
                            window.location.href = action.url;
                        } else if (action.type === 'showMessage') {
                            if (action.config.type === 'success') {
                                message.success(action.config.text)
                            } else if (action.config.type === 'error') {
                                message.error(action.config.text)
                            }
                        } else if (action.type === 'customJS') {
                            // 不清楚这段代码的可以看看MDN文档
                            const func = new Function('context', 'args', action.code);
                            func({
                                name: component.name, props: component.props, showMessage(content: string) {
                                    message.success(content)
                                }
                            }, args);
                        } else if (action.type === 'componentMethod') {
                            const exposeObject = componentRefs.current[action.config.componentId];
                            if (exposeObject) {
                                exposeObject[action.config.method]?.(...args);
                            }
                        }
                    })
                }
            }
        })

        console.log(props);

        return props;
    }

    const componentRefs = useRef<Record<string, any>>({})

    const renderComponents = (components: Component[]): React.ReactNode => {
        return components.map((component: Component) => {
            const config = componentConfig?.[component.name];
            if (!config?.prod) return null;
            return React.createElement(config.prod, {
                key: component.id,
                id: +component.id,
                name: component.name,
                styles: component.styles,
                ref: config.prod.$$typeof === Symbol.for('react.forward_ref') ? (ref: Record<string, any>) => { componentRefs.current[component.id] = ref } : undefined,
                ...config.defaultProps,
                ...component.props,
                ...handleEvent(component)
            }, renderComponents(component.children || []))
        })
    }

    return <div>
        {renderComponents(components)}
    </div>
}